package gobelinmaker.server;

import com.pi4j.component.motor.impl.GpioStepperMotorComponent;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPin;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;

/**
 * Léptetőmotor vezérlőjének alaposztálya.
 *
 * @author imruf84
 */
public class StepperMotorControl extends MotorControl {

    /**
     * Motor komponens.
     */
    private final GpioStepperMotorComponent motor;
    /**
     * Lépéssorozat.
     */
    private final StepperMotorStepSequence sequence;

    /**
     * Konstruktor.
     *
     * @param ID motor azonosítója
     * @param pins tüskék
     * @param sequence lépéssorozat
     * @param direction irány
     */
    public StepperMotorControl(
            String ID,
            GpioPinDigitalOutput pins[],
            StepperMotorStepSequence sequence,
            long direction) {

        super(ID, direction);

        motor = new GpioStepperMotorComponent(pins);

        this.sequence = sequence;

        for (GpioPin pin : pins) {
            pin.setShutdownOptions(true, PinState.LOW, PinPullResistance.OFF);
        }

        this.motor.setStepsPerRevolution(2038);
        this.motor.setStepSequence(sequence.getSequence());
        this.motor.setStepInterval(sequence.getStepInterval());
    }

    /**
     * Tüskék átalakítása az ősosztály által is kezelhető formátumra.
     *
     * @param pins tüskék
     * @return átalakított tüskék
     */
    public static GpioPinDigitalOutput[] pinsToPDO(Pin pins[]) {
        GpioController gpio = GpioFactory.getInstance();
        GpioPinDigitalOutput result[] = new GpioPinDigitalOutput[pins.length];

        for (int i = 0; i < pins.length; i++) {
            result[i] = gpio.provisionDigitalOutputPin(pins[i], PinState.LOW);
        }

        return result;
    }

    @Override
    public void doSteps(long stepsCount) {
        this.motor.step(16 * stepsCount * this.getMicroStepSize() * this.getDirection());
        super.doSteps(stepsCount);
    }

    @Override
    public long getMicroStepSize() {
        return this.sequence.getMicroStepsCount();
    }

    @Override
    public void stop() {
        this.motor.stop();
    }
}
